package com.nulldev.util.networking.async2.udp;

import java.net.DatagramPacket;

import com.nulldev.util.networking.async2.events.ManualResetEvent;

public final class OutgoingUDPServerPacket implements Runnable {
	private ManualResetEvent fDone = new ManualResetEvent(false);
	private boolean fCancel = false;
	private UDPListener fListener;
	private DatagramPacket fData;
	private OutgoingUDPServerPacket fPreviousPacket;

	public OutgoingUDPServerPacket(final UDPListener listener, final DatagramPacket packet, final OutgoingUDPServerPacket previousPacket) {
		this.fListener = listener;
		this.fData = packet;
		listener.getUDPServer().fThreadPool.execute(this);
	}

	public void cancel() {
		this.fCancel = true;
		this.fDone.set();
	}

	@Override
	public void run() {
		try {
			if (this.fPreviousPacket == null) {
				this.fListener.fSocket.send(this.fData);
				this.fListener.fBytesOut += this.fData.getLength();
			} else {
				this.fPreviousPacket.fDone.waitOne();
				if (!this.fCancel && !this.fPreviousPacket.fCancel) {
					this.fListener.fSocket.send(this.fData);
					this.fListener.fBytesOut += this.fData.getLength();
				} else {
					this.fCancel = true;
				}
			}
		} catch (Exception ex) {
		}

		if (this.fPreviousPacket != null) {
			this.fPreviousPacket = null;
		}

		this.fDone.set();
	}

	/**
	 * Returns the DatagramPacket of this outgoing UDP packet.
	 *
	 * @return the DatagramPacket of this outgoing UDP packet.
	 */
	public DatagramPacket getData() {
		return this.fData;
	}

	/**
	 * Returns the previus outgoing packet of the server. If the packet is null
	 * means that the packet has been send.
	 *
	 * @return the previus outgoing packet of the server.
	 */
	public OutgoingUDPServerPacket getPreviusPacket() {
		return this.fPreviousPacket;
	}
}
